<template>
  <a-button @click="handleDraw">开始淹没分析</a-button>
  <div id="cesiumContainer"></div>
</template>
<script setup>
import * as Cesium from "cesium";
import TOKEN from "@/utils/cesium/token.js";
import CesiumTool from '@/utils/newCesiumTool/CesiumTool.js'
import * as turf from '@turf/turf';

const cesiumObj = {
  viewer: null,
  cesiumDraw: null
}
let viewer;
let terrainProviderLoad = false;// 地图信息是否加载
onMounted(async () => {
  Cesium.Ion.defaultAccessToken = TOKEN;
  // 实例化
  viewer = new Cesium.Viewer("cesiumContainer", {
    // 界面控件 全部关闭
    animation: false, // 左下角的动画控制器组件
    baseLayerPicker: false, // 底图组件，选择三维数字地球的底图（imagery and terrain）。
    fullscreenButton: true, // 全屏组件
    vrButton: false, // VR模式
    geocoder: false, // 地理编码（搜索）组件
    homeButton: false, // 首页，点击之后将视图跳转到默认视角
    infoBox: false, // 信息框
    sceneModePicker: false, // 场景模式，切换2D、3D 和 Columbus View (CV) 模式。
    selectionIndicator: false, //是否显示选取指示器组件
    timeline: false, // 时间轴
    navigationHelpButton: false, // 帮助提示，如何操作数字地球。
    // 如果最初应该看到导航说明，则为true；如果直到用户明确单击该按钮，则该提示不显示，否则为false。
    navigationInstructionsInitiallyVisible: false,
  });
  cesiumObj.viewer = viewer
  // 隐藏logo
  viewer._cesiumWidget._creditContainer.style.display = "none";
  // 资产地形
  // 启用 FPS 显示
  viewer.scene.debugShowFramesPerSecond = true;
  cesiumObj.cesiumDraw = new CesiumTool.CesiumDraw(viewer) // 绘制类

  // 加载地形
  const terrainProvider = await Cesium.CesiumTerrainProvider.fromIonAssetId(1);
  viewer.terrainProvider = terrainProvider; // 使用地形

  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(100, 31, 15000.0),
  });

  // 监听地形瓦片加载进度事件
  viewer.scene.globe.tileLoadProgressEvent.addEventListener((tilesLoading) => {
    if (tilesLoading === 0) {
      terrainProviderLoad = true
      console.log("地形加载完成");
      // 可以在这里执行其他操作，比如开启用户交互或显示加载完成提示
    } else {
      terrainProviderLoad = false
      console.log(`还有 ${tilesLoading} 个地形瓦片正在加载`);
    }
  });
});
async function handleDraw() {
  if (!terrainProviderLoad) return console.error('地形数据还未加载,请加载后执行操作')
  const viewer = cesiumObj.viewer
  try {
    viewer.scene.globe.depthTestAgainstTerrain = true; // 开启深度检测
    const res = await cesiumObj.cesiumDraw.drawPromise('Polygon', false)
    console.log('绘制完成', res)
    
    const pointList = res.pointList
    const positionList = res.positionList
    // 细分多边形范围线，根据地形高度，得到多边形最小高度与最大高度
    const { minWaterHeight, maxWaterHeight, } = await getPolygonMinMaxHeight(viewer, pointList)
     // 预警水位线
    const warningWaterHeight = (minWaterHeight + maxWaterHeight) / 2 
    // 预警多边形
    const warningShape = viewer.entities.add({ 
      polygon: {
        hierarchy: positionList,
        material: Cesium.Color.RED.withAlpha(0.2),
        extrudedHeight: Number(warningWaterHeight),
        outline: true,
        outlineColor: Cesium.Color.RED,
        outlineWidth: 4,
      }
    })
    // 当前水位
    let waterHeight = Number(minWaterHeight); // 当前水位线

    const waterShape = viewer.entities.add({
      polygon: {
        hierarchy: positionList,
        extrudedHeight: new Cesium.CallbackProperty(() => {
          return waterHeight
        }, false),
        material: Cesium.Color.fromBytes(64, 157, 253, 150),
      }
    });
    const speed = 1
    const waterHeightTimmer = setInterval(() => {
      waterHeight += Number(speed);
      console.log('waterHeight',waterHeight)
      if (waterHeight > maxWaterHeight || waterHeight < minWaterHeight) {
        window.clearInterval(waterHeightTimmer)
        waterHeight = waterHeight > maxWaterHeight ? maxWaterHeight : minWaterHeight;
      }
    }, 100)
  } catch (e) {
    console.error(e)
  }
}


/**
 * 用于细分颗粒度，取范围线上最大高度与最小高度
 * @param viewer 
 * @param positions [[130.23,32.2],[131.22,33.23]] 经纬度坐标数组
 */
const getPolygonMinMaxHeight = (viewer, positions) => {
  return new Promise(async (resolve, reject) => {
    try {
      console.log('positions', JSON.parse(JSON.stringify(positions)))
      let startP = positions[0];
      let endP = positions[positions.length - 1];
      if (startP.x != endP.x && startP.y != endP.y && startP.z != endP.z) {
        positions.push(positions[0]);
      }
      let line = turf.lineString(positions); // 创建一个线字符串 (LineString) 的 GeoJSON 对象。
      let chunk = turf.lineChunk(line, 10, { units: 'meters' }); // 将线字符串切分为长度为 10 米的段。
      console.log('line', line)
      console.log('chunk', chunk)
      const tempArray = [];
      chunk.features.forEach(f => {
        f.geometry.coordinates.forEach(c => {
          tempArray.push(Cesium.Cartographic.fromDegrees(c[0], c[1]));
        })
      })
      console.log('tempArray', JSON.parse(JSON.stringify(tempArray)))
      const updatedPositions = await Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, tempArray)
      const max = Math.max.apply(Math, updatedPositions.map(item => { return item.height }))
      const min = Math.min.apply(Math, updatedPositions.map(item => { return item.height }))
      const minWaterHeight = Math.ceil(min); // 最小高度
      const maxWaterHeight = Math.ceil(max); // 最大高度
      resolve({
        minWaterHeight,
        maxWaterHeight,
      })
    } catch (e) {
      reject(e)
    }

  })

}

</script>

<style scoped>
#cesiumContainer {
  width: 100%;
  height: 100%;
}
</style>
